package cn.xchats.onlinetraffic.data.server.server;

import cn.xchats.onlinetraffic.common.dto.*;
import cn.xchats.onlinetraffic.common.dto.FieldsDto;
import cn.xchats.onlinetraffic.common.other.http.httpclient.HttpClientUtil;
import cn.xchats.onlinetraffic.common.other.http.java.DownLoadUtil;
import cn.xchats.onlinetraffic.common.other.redis.RedisTemplateService;
import cn.xchats.onlinetraffic.common.other.util.ListUtils;
import cn.xchats.onlinetraffic.common.other.webdriver.PhantomJsUtil;
import cn.xchats.onlinetraffic.common.type.CollectType;
import cn.xchats.onlinetraffic.common.type.CollectWebsiteType;
import cn.xchats.onlinetraffic.data.server.repository.tables.Collectcategory;
import cn.xchats.onlinetraffic.data.server.repository.tables.Fields;
import cn.xchats.onlinetraffic.data.server.repository.tables.*;
import cn.xchats.onlinetraffic.jooq.frame.JooqBaseService;
import cn.xchats.onlinetraffic.jooq.frame.common.MessageBean;
import cn.xchats.onlinetraffic.jooq.frame.common.BaseBean;
import org.jooq.SortField;
import org.jooq.tools.StringUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.*;

/*
 *
 *@author teddy
 *@date 2018/4/16
 */
@Service
@SuppressWarnings("all")
public class CollectorService extends JooqBaseService {

    @Autowired
    private RedisTemplateService redisTemplateService;

    //采集的字段名的key
    private static final String collectCategoryJsSplit = "javaSplit";

    private static final String[] categoryKeyArray = {"1688", "网商园"};

    private static final PhantomJsUtil phantomJsUtil = new PhantomJsUtil();

    //private static final ExecutorService executorService = Executors.newFixedThreadPool(1);

    private static boolean searchImgFlag = false;

    private static Object searchImgFlagLock = new Object();

    /**
     * 获取字段列表
     *
     * @return
     */
    public BaseBean getFieldList() {
        List<FieldsDto> fieldsDtoList = jooqStorage.dslSelect(dsl -> dsl.select().from(Fields.FIELDS).orderBy(Fields.FIELDS.ORDER), FieldsDto.class);
        if (ListUtils.getMethods.isBlank(fieldsDtoList))
            return result("无字段列表");
        return result(fieldsDtoList);
    }

    /**
     * 获取网站分类列表
     *
     * @return
     */
    public BaseBean getCollectWebsiteList() {
        List<String> result = new ArrayList<>();
        result.add(CollectWebsiteType.category_1688);
        result.add(CollectWebsiteType.category_tao_bao);
        result.add(CollectWebsiteType.category_网商园);
        return result(result);
    }

    /**
     * 添加获取字段的js
     *
     * @param fieldName
     * @param value
     * @return
     */
    public BaseBean saveCollectCategory(String category, String fieldName, String value) {
        try {
            CollectCategoryDto collectCategoryDto = new CollectCategoryDto();
            collectCategoryDto.setCategory(category);
            collectCategoryDto.setId(UUID.randomUUID().toString());
            collectCategoryDto.setFieldName(fieldName.trim());
            collectCategoryDto.setExecuteJavascript(value);

            List<CollectCategoryDto> collectCategoryDtos = jooqStorage.listByCondition(Collectcategory.COLLECTCATEGORY, CollectCategoryDto.class, Collectcategory.COLLECTCATEGORY.FIELDNAME.eq(fieldName).and(Collectcategory.COLLECTCATEGORY.CATEGORY.eq(category)));

            if (ListUtils.getMethods.isBlank(collectCategoryDtos)) {
                jooqStorage.create(Collectcategory.COLLECTCATEGORY, CollectCategoryDto.class, collectCategoryDto);
            } else {
                CollectCategoryDto currentCollectCategoryDto = collectCategoryDtos.get(0);
                currentCollectCategoryDto.setExecuteJavascript(currentCollectCategoryDto.getExecuteJavascript() + collectCategoryJsSplit + value);
                jooqStorage.dslDelete(dsl -> dsl.delete(Collectcategory.COLLECTCATEGORY).where(Collectcategory.COLLECTCATEGORY.FIELDNAME.eq(fieldName).and(Collectcategory.COLLECTCATEGORY.CATEGORY.eq(category))));
                jooqStorage.create(Collectcategory.COLLECTCATEGORY, CollectCategoryDto.class, currentCollectCategoryDto);
            }
            return result(collectCategoryDto);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result("添加失败");
    }

    /**
     * 添加字段
     *
     * @param field
     * @return
     */
    public BaseBean saveField(String field, String order) {
        FieldsDto fieldsDto = new FieldsDto();
        try {
            fieldsDto.setId(UUID.randomUUID().toString());
            fieldsDto.setFieldName(field.trim());
            fieldsDto.setOrder(order);

            jooqStorage.create(Fields.FIELDS, FieldsDto.class, fieldsDto);
            return result(fieldsDto);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result("添加失败");
    }

    /**
     * 获取采集的数据集合
     *
     * @param id
     * @param category
     * @return
     */
    public BaseBean getCollectList(String userId, CollectType category, int currentPage, int limit) {
        //分页
        if (currentPage > 0)
            currentPage -= 1;
        currentPage *= limit;

        int homePage = currentPage;

        UserInfoDto userInfoDto = jooqStorage.listByCondition(Userinfo.USERINFO, UserInfoDto.class, Userinfo.USERINFO.USERID.eq(userId)).get(0);
        SortField<Timestamp> sort;
        if ("desc".equals(userInfoDto.getShopSort()))
            sort = Shop.SHOP.ORDERTIME.asc();
        else
            sort = Shop.SHOP.ORDERTIME.desc();
        //先查用户下所有的shop
        //List<ShopDto> shopDtos = jooqStorage.listByCondition(Shop.SHOP, ShopDto.class, Shop.SHOP.USERID.eq(userId).and(Shop.SHOP.CATEGORY.eq(category.name())));
        List<ShopDto> shopDtos = jooqStorage.dslSelect(dsl -> dsl.select().from(Shop.SHOP).where(Shop.SHOP.USERID.eq(userId).and(Shop.SHOP.CATEGORY.eq(category.name()))).orderBy(sort).limit(homePage, limit), ShopDto.class);
        for (int i = 0; i < shopDtos.size(); i++) {
            ShopDto shopDto = shopDtos.get(i);
            //每个商品添加采集的字段值
            List<CollectDto> collectDtos = jooqStorage.dslSelect(dsl -> dsl.select().from(Collect.COLLECT).where(Collect.COLLECT.SHOPID.eq(shopDto.getId())).orderBy(Collect.COLLECT.ORDER), CollectDto.class);
            shopDto.setCollectDtoList(collectDtos);
        }

        if (ListUtils.getMethods.isBlank(shopDtos))
            return result("无数据");
        return result(shopDtos);
    }

    public BaseBean getCollectListCount(String userId, CollectType category) {
        List<ShopDto> shopDtos = jooqStorage.dslSelect(dsl -> dsl.select().from(Shop.SHOP).where(Shop.SHOP.USERID.eq(userId).and(Shop.SHOP.CATEGORY.eq(category.name()))).orderBy(Shop.SHOP.ORDERTIME.asc()), ShopDto.class);
        int count = jooqStorage.dslSelectCount(dsl -> dsl.select().from(Shop.SHOP).where(Shop.SHOP.USERID.eq(userId).and(Shop.SHOP.CATEGORY.eq(category.name()))).orderBy(Shop.SHOP.ORDERTIME.asc()));
        return result(count);
    }

    /**
     * 获取采集规则列表
     *
     * @return
     */
    public BaseBean getCollectRuleList() {
        List<CollectCategoryDto> collectCategoryDtos = jooqStorage.listByCondition(Collectcategory.COLLECTCATEGORY, CollectCategoryDto.class);
        if (ListUtils.getMethods.isBlank(collectCategoryDtos))
            return result("无数据");
        return result(collectCategoryDtos);
    }

    public BaseBean getItemList(String shopParentId, String category) {
        List<ShopDto> shopDtos = jooqStorage.listByCondition(Shop.SHOP, ShopDto.class, Shop.SHOP.PARENTID.eq(shopParentId).and(Shop.SHOP.CATEGORY.eq(category)));
        if (ListUtils.getMethods.isBlank(shopDtos))
            return result("无数据");
        List<ComparisonInfoDto> comparisonInfoDtos = jooqStorage.listByCondition(Comparisoninfo.COMPARISONINFO, ComparisonInfoDto.class, Comparisoninfo.COMPARISONINFO.SHOPID.eq(shopDtos.get(0).getId()));
        if (ListUtils.getMethods.isBlank(comparisonInfoDtos))
            return result("无数据");
        ShopDto shopDto = shopDtos.get(0);
        shopDto.setComparisonInfoDtoList(comparisonInfoDtos);
        return result(shopDto);
    }

    /**
     * 删除商品和关联的商品及内容
     *
     * @param id
     */
    public void deleteShop(String id) {
        try {
            //删除商品采集的数据
            jooqStorage.dslDelete(dsl -> dsl.delete(Collect.COLLECT).where(Collect.COLLECT.SHOPID.eq(id)));
            //删除详情页信息
            List<ShopDto> shopDtos = jooqStorage.listByCondition(Shop.SHOP, ShopDto.class, Shop.SHOP.PARENTID.eq(id));
            if (ListUtils.getMethods.isNotBlank(shopDtos)) {
                for (int i = 0; i < shopDtos.size(); i++) {
                    ShopDto shopDto = shopDtos.get(i);
                    //删除details下的列表数据
                    jooqStorage.dslDelete(dsl -> dsl.delete(Comparisoninfo.COMPARISONINFO).where(Comparisoninfo.COMPARISONINFO.SHOPID.eq(shopDto.getId())));
                    //删除details商品
                    jooqStorage.dslDelete(dsl -> dsl.delete(Shop.SHOP).where(Shop.SHOP.ID.eq(shopDto.getId())));
                }
            }
            //删除home商品
            jooqStorage.dslDelete(dsl -> dsl.delete(Shop.SHOP).where(Shop.SHOP.ID.eq(id)));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 商品是否存在
     *
     * @param type
     * @param shopId
     * @param parentShopId 不查父id 则传null
     * @return
     */
    public BaseBean existShop(CollectType type, String shopUrl, String parentShopId, String userId) {
        //查details
        if (!StringUtils.isBlank(parentShopId)) {
            //商品类目相同，父类和父类所属用户相同
            List<ShopDto> shopDtos = jooqStorage.listByCondition(Shop.SHOP, ShopDto.class, Shop.SHOP.PARENTID.eq(parentShopId).and(Shop.SHOP.CATEGORY.eq(type.name()).and(Shop.SHOP.USERID.eq(userId))));
            if (ListUtils.getMethods.isNotBlank(shopDtos))
                return result(shopDtos);
            return result("current shop not exist.");
        }
        //查shop
        //商品类目相同,商品网址相同，商品所属用户相同
        List<ShopDto> shopDtos = jooqStorage.listByCondition(Shop.SHOP, ShopDto.class, Shop.SHOP.URL.eq(shopUrl).and(Shop.SHOP.CATEGORY.eq(type.name())));
        if (ListUtils.getMethods.isNotBlank(shopDtos))
            return result(shopDtos);
        return result("current shop not exist.");
    }

    protected <T> T getFieldValue(WebDriver webDriver, String executeJavascript) {
        JavascriptExecutor webDriverJS = (JavascriptExecutor) webDriver;
        System.out.println(executeJavascript);
        //String js2="var number=''; var length= $(\".obj-content img\").length; for(var i=0;i<length;i++){number+=$(\".obj-content img\")[i].src+';'} return number;";
        //String result = String.valueOf(webDriverJS.executeScript(js2));
        //System.out.println(result);
        return (T) String.valueOf(webDriverJS.executeScript(executeJavascript));
    }

    public BaseBean checkCollectTaskRecord(CollectType type, String shopUrl, String parentShopId, String userId) {
        StringBuffer searchKey = new StringBuffer();
        searchKey.append(type.name()).append(shopUrl).append(parentShopId).append(userId);
        //先看是否存在记录，不存在则记录
        String result = redisTemplateService.getString(searchKey.toString(), String.class);
        //存在记录不能执行
        if (!StringUtils.isBlank(result)) {
            return result(new Date());
        }
        //添加记录
        redisTemplateService.addString(searchKey.toString(), ".");
        //设置过期时间  2小时
        redisTemplateService.setTimeOut(searchKey.toString(), 1000 * 60 * 60 * 2);
        //redisTemplateService.setTimeOut(searchKey.toString(), 10);
        return result("已添加记录");
    }
}
